package edu.uwm.RobberKnight.Model;

import java.awt.Color;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Stack;

public class Player implements java.io.Serializable{


	private static final long serialVersionUID = 7830953442818583002L;
	public static final int MAX_MOVES = 3;
    public static final int KNIGHTS = 30;
    private Color _color;
    private String _name;
    private int _age;
    private int _score;
    private Stack<Tile> _tiles;
    private LinkedList<Tile> _hand;
    private Stack<Knight> _knights;

    protected Player(String name, Color color, int age) {
        _name = name;
        _color = color;
        _age = age;
        _tiles = new Stack<Tile>();
        _hand = new LinkedList<Tile>();
        _knights = new Stack<Knight>();
        for (int i = 0; i < KNIGHTS; i++) {
            _knights.add(new Knight(this));
        }

        Collection<Tile> a = new Stack<Tile>();
        Collection<Tile> b = new Stack<Tile>();
        Collection<Tile> c = new Stack<Tile>();
        Collection<Tile> d = new Stack<Tile>();
        Collection<Tile> e = new Stack<Tile>();

        a.add(new Tile(TileType.CASTLE_PLAIN, this, 'A'));

        _hand.add(new Tile(TileType.VILLAGE_PLAIN, this, 'A'));
        _hand.add(new Tile(TileType.MOUNTAIN, this, 'A'));
        _hand.add(new Tile(TileType.PLAIN, this, 'A'));

        b.add(new Tile(TileType.VILLAGE_PLAIN, this, 'B'));
        b.add(new Tile(TileType.VILLAGE_FOREST, this, 'B'));
        b.add(new Tile(TileType.CASTLE_PLAIN, this, 'B'));
        b.add(new Tile(TileType.TOWN_PLAIN, this, 'B'));
        b.add(new Tile(TileType.LAKE, this, 'B'));
        Collections.shuffle((List<?>) b);

        c.add(new Tile(TileType.PLAIN, this, 'C'));
        c.add(new Tile(TileType.VILLAGE_PLAIN, this, 'C'));
        c.add(new Tile(TileType.CASTLE_PLAIN, this, 'C'));
        c.add(new Tile(TileType.CASTLE_FOREST, this, 'C'));
        c.add(new Tile(TileType.TOWN_FOREST, this, 'C'));
        Collections.shuffle((List<?>) c);

        d.add(new Tile(TileType.CASTLE_PLAIN, this, 'D'));
        d.add(new Tile(TileType.MOUNTAIN, this, 'D'));
        d.add(new Tile(TileType.VILLAGE_FOREST, this, 'D'));
        d.add(new Tile(TileType.TOWN_PLAIN, this, 'D'));
        d.add(new Tile(TileType.CASTLE_PLAIN, this, 'D'));
        Collections.shuffle((List<?>) d);

        e.add(new Tile(TileType.PLAIN, this, 'E'));
        e.add(new Tile(TileType.CASTLE_PLAIN, this, 'E'));
        e.add(new Tile(TileType.VILLAGE_FOREST, this, 'E'));
        e.add(new Tile(TileType.TOWN_PLAIN, this, 'E'));
        e.add(new Tile(TileType.CASTLE_FOREST, this, 'E'));
        Collections.shuffle((List<?>) e);

        _tiles.addAll(e);
        _tiles.addAll(d);
        _tiles.addAll(c);
        _tiles.addAll(b);
        _tiles.addAll(a);
    }
    /*
     * Returns true if the player has played all their tiles. Otherwise returns
     * false. Indicated by the player having an empty hand collection.
     */

    public boolean isFinished() {
        if (_tiles.isEmpty()) {
            return true;
        }
        return false;
    }

    /*
     * Returns the corresponding name of the player.
     */
    public String getName() {
        return _name;
    }

    /*
     * Returns the corresponding age of the player.
     */
    public int getAge() {
        return _age;
    }

    /*
     * Returns the corresponding score of the player.
     */
    public int getScore() {
        return _score;
    }

    protected void setScore(int score) {
        _score = score;
    }

    /*
     * Pops the top tile from the player's stack and places it into the hand in
     * place of the passed tile.
     */
    protected boolean placeTile(Tile tile, int x, int y, Board board) {

    	if(tile.place(x, y, board)){
        	if (_hand.contains(tile)) {
            _hand.remove(tile);
        	} else {
        		return false;
        	}
        
	        if (_hand.size() < 2 && _tiles.size() > 0) {
	            _hand.add(_tiles.pop());
	        }
        } else {
        	return false;
        }
        
        
        return true;
    }

    /*
     * Returns the corresponding color of the player.
     */
    public Color getColor() {
        return _color;
    }

    /*
     * Returns the stack of tiles currently on the player's tile stack.
     */
    @SuppressWarnings("unchecked")
    public LinkedList<Tile> getHand() {
        return (LinkedList<Tile>) _hand.clone();
    }

    /*
     * Pop a knight off the player's knight stack and return it.
     */
    protected Knight removeKnight() {
        Knight k = _knights.pop();
        return k;

    }

    public int getTilesSize() {
        return _tiles.size();
    }
    
    public int getHandSize() {
    	return _hand.size();
    }
    
    public int getKnightsSize() {
    	return _knights.size();
    }
    
    public char getTopTileChar() {
    	char letter = ' ';
    	if(_tiles.size() > 0) {
	    	Tile top = _tiles.peek();
	    	if(top != null)
	    		letter = top.getLetter();
    	}
    	return letter;
    }
}
